/**
 * 高途行课，读xing
 * @file
 * @author baizhaolei@baijia.com, caohuayu@baijia.com
 * @date 2020-05-18
 */
/**
 * @author niumijia@baijia.com
 * mock数据的配置:
 * isinput: 输入框是什么格式, 是否是日期格式;
 *     isinput == 0: 不为日期, 代表option为单选
 *     isinput == 1: 不为日期, 目测是个输入框
 *     isinput == 2: 不为日期, 还不知道
 *     isinput == 3: 不为日期, 代表option为多选
 *     isinput == 4/5/6/7/8: 都代表日期输入为时间区间，每个数字不同代表日期的精确单位不同。具体看dateRanges.js
 *     isinput == 9:代表日期输入为时间点(这个是后加的)
 * hidden: 该输入框是否显示; 为0时显示, 为1时不显示
 * dimensionId: 代表该输入框的id号, 1个json文件唯一
 * dimensionName: 代表该输入框的名称
 * taskId: 好像为每个模块的的id号,目测一个json文件都一样
 * filterItem: 当输入框为日期时: 为时间区间; 转换成时间具体为dateRange.js中的RANGE_NAME_ENUM和getRangeDate(value)
 *             当输入框为input/option时, 为输入框的选择内容。
 * -----------------------------------------------------------------------------
 * 发现没用到的配置: (判断依据: 在src文件夹中没有用到这些变量名)
 * admDimension, admDimensionField, hyperLink, parameter,ispublic
 * -----------------------------------------------------------------------------
 * 我还没看到的配置:
 * isopen
 * sn: 是大屏配置里需要用到的属性,用来表格排序。
 */

/**
 * 高途行课和好课行课的区别:
 *  1. 高途行课是“课节序号”,是一个不固定的值;好课行课是“课节”,是一个固定的值,恒为2666
*/

/**
 * 高途行课问题:
 *  1. "展开/收齐" 不好用,因为只有9个控件,就先没改
*/
import {Component} from 'react';
import {Card, message} from 'antd';
import {
    fetchReports, downloadReports, getReportInfo, getReportIdList
} from '~/service/reports';
import {lineOptions as produceOptions} from '~/utils/common/reportEcharts';
import WrapperForm from '~/component/SearchForm';
import getRange, {isTimeRange, isTimePoint, INPUT_TYPE_ENUM} from '~/component/SearchForm/dateRanges';

import {groupByData, generateColumns, getFormatter} from './utils/indicator';
import RealTimeStatisticsView from './RealtimeStatisticsView';
import OrderTimeView from './OrderTimeView';
import CollectListView from './CollectListView';

import './index.styl';


const xingkeSign = 'gaotuXingke';
class GaoTuXingKeReport extends Component {
    constructor(props) {
        super(props);
        this.state = {
            // 接口请求 permissions,统计,汇总使用一套
            permissions: [],
            // collect转变id
            firstDimensions: null,
            collectDimensions: null,
            downloadPermissions: [],
            // 接口请求 permissions,下单时间 第三块的数据
            orderPermissions: [],
            downloadOrderPermissions: [],
            // echart options
            dataMapOptions: null,
            // orderTime echart options
            orderDataMapOtios: null,
            // 数据详情
            isloading: false,
            // 下单loading
            isOrderLoading: false,
            // 实时统计 columns
            columns: [],
            // 汇总 columns
            collectColumns: [],
            // orderTime columns
            orderTimeColumns: [],
            // 实时统计 datasouce
            dataSource: [],
            // 汇总 datasource
            collectDatasource: [],
            // orderTime dateSource
            orderTimeDataSource: [],
            downLoading: false,
            // 时间的类型，替代period, 分，小时，日周月， 默认 日
            period: INPUT_TYPE_ENUM.DAY,
            // 实时统计使用
            dateDim: 'dimension1',
            // 下单时间统计使用
            orderTimeDateDim: 'dimension1',
            // 统计表的id
            statisticsId: '',
            // 汇总表的id
            collectId: '',
            // 下单时间统计
            orderTimeId: '',
            newXvalue: null,
            // 查询课节数
            searchLessonsNum: 0,
            addSearchLessonsNum: 0,
            hasAdded: false
        };
    }

    componentDidMount() {
        this.getReportsId();
    }

    componentWillUnmount() {
        // 卸载异步操作设置状态
        this.setState = (state, callback) => false;
    }

    // 查询统计数据
    onStaticSearch = (permissions = []) => {
        // 报表1 id
        const {statisticsId, collectId} = this.state;

        //  验证前置
        const isCanSearch = this.verificateClick(statisticsId, permissions);
        if (!isCanSearch) {
            return;
        }

        this.setState({
            downloadPermissions: permissions
        });

        // 同时搜索report1 report2
        this.onSearch(permissions, statisticsId);

        // change id
        this.onSearch(this.changeDimensionId(permissions), collectId);
    };

    // 添加对比
    onAddOk = params => {
        const {permissions} = params;
        const {statisticsId} = this.state;
        this.onSearch(permissions, statisticsId, true);
    };

    // 清除操作
    onClear = () => {
        const {dataMapOptions, newXvalue, searchLessonsNum} = this.state;
        if (newXvalue) {
            const options = dataMapOptions;
            options.legend.data = options.legend.data.slice(0, searchLessonsNum);
            options.series = options.series.slice(0, searchLessonsNum);
            options.tooltip.formatter = null;
            // 是否默认选中
            const select = {};
            for (const item of options.legend.data) {
                select[item] = false;
                if (item.indexOf('在线人数') !== -1) {
                    select[item] = true;
                }
            }
            options.legend.selected = select;

            this.setState({
                dataMapOptions: options,
                newXvalue: null,
                hasAdded: false,
                addSearchLessonsNum: 0
            });
        }
        else {
            message.warning('还未添加对比数据');
        }
    };

    // 查询下单时间数据
    onOrderTimeSearch = permissions => {
        const {orderTimeId} = this.state;
        this.setState({
            downloadOrderPermissions: permissions
        });
        this.onSearch(permissions, orderTimeId);
    };

    // 查询功能，isAdd 是否添加对比
    onSearch = (params, id, isAdd = false) => {
        if (this.verificateClick(id, params)) {
            this.getReports(params, id, isAdd);
        }
    };

    // 统一下载
    onDownloadReport = id => {
        const {downloadPermissions, downloadOrderPermissions, orderTimeId, statisticsId, collectId} = this.state;
        // 只请求有 参数维度
        let newPermissions = null;
        if (orderTimeId === id) {
            newPermissions = downloadOrderPermissions;
        }
        else {
            newPermissions = downloadPermissions;
        }

        const isCanDownLoad = this.verificateClick(id, newPermissions, true);
        if (!isCanDownLoad) {
            return;
        }

        newPermissions = newPermissions.filter(item => item.filterItems.length > 0);

        // 拼接name
        let name = '';
        if (orderTimeId === id) {
            name = newPermissions.length > 1
                ? `下单时间分布_${newPermissions[1].filterItems[0]}`
                : '下单时间分布';
        }
        else if (id === statisticsId) {
            name = `直播到课统计${name}`;
        }
        else {
            // 汇总，需要改dimensionId
            newPermissions = this.changeDimensionId(newPermissions);
            name = `课节汇总数据${name}`;
        }

        const param = {
            id,
            permissions: newPermissions,
        };
        this.setState({
            downLoading: true
        });
        downloadReports(param, name, this.callback).catch(() => {
            message.error('下载失败，请重试！');
            this.setState({
                downLoading: false
            });
        });
    };

    // 验证点击操作
    verificateClick = (id, newPermissions, isDownLoad) => {
        const {orderTimeId, dataSource, orderTimeDataSource} = this.state;
        if (orderTimeId === id) {
            if (isDownLoad && !orderTimeDataSource.length) {
                message.warning('请先查询数据');
                return false;
            }
            if (newPermissions[1].filterItems.length === 0) {
                message.warning('请选择班级Id');
                return false;
            }
        }
        else {
            if (isDownLoad && !dataSource.length) {
                message.warning('请先查询数据');
                return false;
            }
            for (const index in newPermissions) {
                if (newPermissions[index].filterItems.length !== 0) {
                    break;
                }
                if (Number(index) === newPermissions.length - 1) {
                    message.warning('请先输入数据');
                    return false;
                }
            }
        }
        return true;
    };

    // 获取报表的三个id, 传进来的id是路由id
    getReportsId = () => {
        const {match: {params: {id}}} = this.props;
        getReportIdList(id)
            .then(res => {
                const {data: {idList}} = res;
                this.setState({
                    statisticsId: idList[0],
                    collectId: idList[1],
                    orderTimeId: idList[2]
                }, () => {
                    this.reportDetail(idList[0]);
                    this.reportDetail(idList[1]);
                    // this.reportDetail(idList[2]);
                });
            });
    };

    // 获取报表详情
    reportDetail = id => {
        const {statisticsId, collectId} = this.state;
        getReportInfo({id})
            .then(res => {
                const {data: {reportDimension}} = res;
                const permissions = reportDimension.filter(item => !item.hidden).map(item => {
                    const i = {
                        dimensionId: item.dimensionId,
                        isinput: item.isinput,
                        dimensionName: item.dimensionName,
                        taskId: item.taskId,
                    };
                    if (isTimeRange(item.isinput) || isTimePoint(item.isinput)) {
                        // getRange函数的作用是为了将文字的时间转换成代码，返回相应的时间区间形成数组。
                        // eg: “当日”: 返回[ 今天0:00, 今天23:59 ]
                        // 当为“”或者“全部”时，默认返回[ 6天前的0点, 当天23:59点 ]
                        i.filterItems = getRange(item.filterItem);
                        this.setState({
                            period: item.isinput
                        });
                    }
                    else if (item.filterItem instanceof Array) {
                        i.filterItems = item.filterItem;
                    }
                    else if (item.filterItem === '') {
                        i.filterItems = [];
                    }
                    else {
                        i.filterItems = [item.filterItem];
                    }
                    return i;
                });
                if (statisticsId === id) {
                    this.setState({
                        permissions,
                        firstDimensions: permissions
                    });
                }
                else if (collectId === id) {
                    this.setState({
                        collectDimensions: permissions
                    });
                }
                else {
                    this.setState({orderPermissions: permissions});
                }
            })
            .catch(error => {
                if (error) {
                    console.log(error, 'error');
                }
            });
    };

    // 获取echart数据
    getDataMap = (dataSource, id, isToAdd) => {
        const {
            period, dateDim, orderTimeDateDim, columns, orderTimeColumns,
            statisticsId, dataMapOptions, newXvalue, searchLessonsNum,
            addSearchLessonsNum, hasAdded
        } = this.state;
        let data = [];
        const newColumns = statisticsId === id ? columns : orderTimeColumns;
        const newDateDim = statisticsId === id ? dateDim : orderTimeDateDim;
        for (const item of newColumns) {
            if (item.key.indexOf('field') !== -1) {
                data = data.concat(groupByData(dataSource, newDateDim, item.key, item.title.props.title));
            }
        }
        const options = produceOptions(data, period);
        if (statisticsId === id) {
            if (isToAdd) {
                options.legend.data = dataMapOptions.legend.data.slice(0, searchLessonsNum).concat(options.legend.data);
                options.series = dataMapOptions.series.slice(0, searchLessonsNum).concat(options.series);
                const newXvalue = options.xAxis.data;
                options.xAxis = dataMapOptions.xAxis;
                options.tooltip.formatter = getFormatter(newXvalue, options, searchLessonsNum);
                this.setState({
                    newXvalue,
                    hasAdded: true
                });
            }
            if (!isToAdd && hasAdded) {
                options.legend.data = options.legend.data.concat(
                    dataMapOptions.legend.data.slice(-addSearchLessonsNum)
                );
                options.series = options.series.concat(dataMapOptions.series.slice(-addSearchLessonsNum));
                options.tooltip.formatter = getFormatter(newXvalue, options, searchLessonsNum);
            }
            // 是否默认选中
            const select = {};
            for (const item of options.legend.data) {
                select[item] = false;
                // TODO: 修改成 在线人数
                if (item.indexOf('在线人数') !== -1) {
                    select[item] = true;
                }
            }
            options.legend.selected = select;
        }
        // Y轴间距只能是正整数
        options.yAxis.minInterval = 1;
        // 添加底部拖动
        options.dataZoom = [
            {
                type: 'slider',
                show: true,
                realtime: true,
                start: 0,
                end: 100
            }
        ];
        const stateData = {};
        statisticsId === id
            ? stateData.dataMapOptions = options
            : stateData.orderDataMapOtios = options;
        this.setState(stateData);
    };

    // 查询获取数据详情
    getReports = (permissions, id, isAdd) => {
        const {statisticsId, collectId, orderTimeId, period} = this.state;
        orderTimeId === id
            ? this.setState({isOrderLoading: true})
            : this.setState({isloading: true});
        // 只请求有 参数维度
        let length = 1;
        permissions = permissions.filter(item => {
            const itemLengt = item.filterItems.length;
            length = itemLengt > length ? itemLengt : length;
            return itemLengt > 0;
        });
        const param = {
            id,
            permissions,
        };
        // 设置查询课节的线数
        if (isAdd) {
            this.setState({
                addSearchLessonsNum: length * 3
            });
        }
        else {
            this.setState({
                searchLessonsNum: length * 3
            });
        }

        fetchReports(param)
            .then(res => {
                let {columns, dataSource} = res.data;
                // 渲染table
                columns = generateColumns(columns, period);

                const columnsFilter = columns.filter(item => item.title.props.title === '日期');
                const dateDim = columnsFilter.length > 0 ? columnsFilter[0].key : '';
                const staticData = {
                    dateDim,
                    isloading: false,
                };
                const collectData = {
                    isloading: false,
                };
                if (!isAdd) {
                    staticData.dataSource = dataSource;
                    staticData.columns = columns;
                    collectData.collectColumns = columns;
                    collectData.collectDatasource = dataSource;
                }
                const orderData = {
                    orderTimeDateDim: dateDim,
                    isOrderLoading: false,
                    orderTimeDataSource: dataSource,
                    orderTimeColumns: columns
                };
                if (collectId === id) {
                    this.setState(collectData);
                }
                else {
                    const stateData = statisticsId === id ? staticData : orderData;
                    this.setState(stateData, () => {
                        // 请求获取map
                        this.getDataMap(dataSource, id, isAdd);
                    });
                }

            })
            .catch(() => {
                this.setState({
                    isloading: false,
                    isOrderLoading: false
                });
            });
    };

    // 下单重置数据
    handleOrderTimeReset = () => {
        const {permissions} = this.state;
        const temp = permissions;
        if (temp.length !== 0) {
            for (const item of temp) {
                item.filterItems = [];
            }
        }
        this.setState({
            orderTimeColumns: [],
            orderTimeDataSource: [],
            orderDataMapOtios: null,
            permissions: temp
        });
    };

    // 统计重置数据
    handleReset = () => {
        const {orderPermissions} = this.state;
        const temp = orderPermissions;
        if (temp.length !== 0) {
            temp[1].filterItems = [];
        }
        this.setState({
            columns: [],
            dataSource: [],
            collectColumns: [],
            collectDatasource: [],
            dataMapOptions: null,
            orderPermissions: temp,
            searchLessonsNum: 0,
            addSearchLessonsNum: 0
        });
    };

    callback = () => {
        this.setState({
            downLoading: false
        });
    };

    changeDimensionId = param => {
        const {firstDimensions, collectDimensions} = this.state;

        const matching = new Map();
        for (const ele1 of collectDimensions) {
            for (const ele2 of firstDimensions) {
                if (ele1.dimensionName === ele2.dimensionName) {
                    matching.set(ele2.dimensionId, ele1.dimensionId);
                }
            }
        }
        const res = [];
        for (const e of param) {
            res.push({
                ...e,
                dimensionId: matching.get(+e.dimensionId) || e.dimensionId
            });
        }
        return res;
    };

    render() {
        const {
            dataMapOptions, orderDataMapOtios, isOrderLoading, permissions, orderPermissions,
            orderTimeDataSource, isloading, dataSource, downLoading,
            statisticsId, collectId, orderTimeId, collectColumns,
            collectDatasource
        } = this.state;

        return (
            <div className="gaoTuXingKe">
                <Card>
                    <h3>实时到课数据统计</h3>
                    <WrapperForm
                        data={permissions}
                        onSearch={this.onStaticSearch}
                        onHandleReset={this.handleReset}
                        isLoading={isloading}
                        id={statisticsId}
                        xingkeSign={xingkeSign}
                    />
                    <RealTimeStatisticsView
                        isloading={isloading}
                        dataSource={dataSource}
                        dataMapOptions={dataMapOptions}
                        statisticsId={statisticsId}
                        data={permissions}
                        onDownloadReport={this.onDownloadReport}
                        onOk={this.onAddOk}
                        onClear={this.onClear}
                    />
                </Card>

                <Card className="divide">
                    <CollectListView
                        downLoading={downLoading}
                        columns={collectColumns}
                        dataSource={collectDatasource}
                        onDownloadReport={this.onDownloadReport}
                        collectId={collectId}
                        isloading={isloading}
                    />
                </Card>

            </div>
        );
    }
}

export default GaoTuXingKeReport;
